import os
import subprocess
import sys

import requests
from PyQt5.QtCore import Qt, QJsonDocument, QJsonParseError, pyqtSignal, QThread, QUrl
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PyQt5.QtWidgets import QWidget

from Ui_Update import Ui_Update
from globalvar import golbalvar


class Update(QWidget):
    relayFinishedSignal = pyqtSignal()
    def __init__(self, parent=None):
        super(Update, self).__init__(parent)
        self.downloadThread = None
        self.update_window = QWidget()
        self.ui = Ui_Update()
        self.ui.setupUi(self)
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint | Qt.MSWindowsFixedSizeDialogHint)
        self.manager = QNetworkAccessManager(self)
        self.manager.finished.connect(self.relayFinished)
        self.relayFinishedSignal.connect(self.refresh_update)
        # 获取全局参数
        self.curvesion = golbalvar.get_value('curversion')
        self.url = golbalvar.get_value('update_url')
        self.software_update = golbalvar.get_value('softwareUpdate')
        self.set_ui()
        # 局部参数
        self.filepath = None
        # 自检是否升级
        url = QUrl(self.url + self.software_update)
        self.manager.get(QNetworkRequest(url))


    def set_ui(self):
        self.ui.pushButton_Need_OK.clicked.connect(self.close)
        self.ui.pushButton_Need_Update.clicked.connect(self.show_downloading)

    def show_downloading(self):
        # 切换页面
        self.refresh_window(3)
        # 开始下载任务
        the_url = self.url + self.filepath
        the_filesize = requests.get(the_url, stream=True).headers['Content-Length']
        if os.path.isfile(self.filepath):
            os.remove(self.filepath)
        the_fileobj = open(self.filepath, 'wb+')
        # 创建下载线程
        self.downloadThread = downloadThread(the_url, the_filesize, the_fileobj, buffer=102400)
        self.downloadThread.download_proess_signal.connect(self.set_progressbar_value)
        self.downloadThread.start()

    def set_progressbar_value(self, value):
        self.ui.progressBar.setValue(value)
        if value == 100:
            self.ui.label_download_info.setText("下载完成")
            if os.path.isfile("upgrade.bat"):
                os.remove("upgrade.bat")
            self.writeUpgrade(self.filepath)

    def relayFinished(self, reply):
        index_now = 0
        str1 = reply.readAll()
        err = QJsonParseError()
        json_revev = QJsonDocument.fromJson(str1, err)
        if not json_revev.isNull():
            myobject = json_revev.object()
            if 'LatestVerison' in myobject:
                latestVersion = myobject['LatestVerison'].toString()
                if self.curvesion == latestVersion:
                    index_now = 0
                elif self.curvesion < latestVersion:
                    index_now = 1
                    # 显示升级内容
                    ReleaseNote = myobject['ReleaseNote'].toString()
                    UpdateTime = myobject['UpdateTime'].toString()
                    text = "升级内容:" + "\n" + latestVersion + ReleaseNote + "\n" + "发布时间：" + UpdateTime
                    self.ui.label_softversion.setText(text)
                    # 获取文件路径
                    self.filepath = myobject['file'].toString()
                else:
                    index_now = 0
        else:
            index_now = 0
        reply.deleteLater()
        if index_now == 1:
            self.relayFinishedSignal.emit()

    def refresh_window(self, index):
        self.ui.StackedWidget.setCurrentIndex(index)
        self.ui.StackedWidget.show()
        self.show()

    def update_check(self):
        self.refresh_window(4)
        url = QUrl(self.url + self.software_update)
        self.manager.get(QNetworkRequest(url))
        self.refresh_window(0)

    def refresh_update(self):
        self.refresh_window(1)

    def writeUpgrade(self, exe_name):
        # 获取当前exe文件的路径
        current_exe = os.path.abspath(sys.executable)
        upgrade_batch = "upgrade.bat"
        b = open(upgrade_batch, 'w')
        templist = "@echo off\n"
        templist += f"if not exist " + exe_name + " exit \n"
        templist += f"taskkill /F /IM {os.path.basename(current_exe)}\n"  # 强制结束当前exe进程
        templist += f"sleep 3\n"  # 延时3秒（等待进程结束）
        templist += f"del /f /q \"{current_exe}\"\n"  # 删除当前exe文件
        templist += f"start " + exe_name + "\n"  # 启动新程序
        templist += f"del /f /q \"{upgrade_batch}\"\n"  # 删除自身的升级脚本
        b.write(templist)
        b.close()
        subprocess.Popen("upgrade.bat")
        # 这里不直接退出，因为一旦退出，upgrade.bat可能还未完成任务
        # 等待批处理脚本执行完毕（实际应用中可能需要更复杂的同步机制来确保批处理完成）
        sys.exit()


class downloadThread(QThread):
    download_proess_signal = pyqtSignal(int)

    def __init__(self, url, filesize, fileobj, buffer):
        super(downloadThread, self).__init__()
        self.url = url
        self.filesize = filesize
        self.fileobj = fileobj
        self.buffer = buffer

    def run(self):
        try:
            rsp = requests.get(self.url, stream=True)
            offset = 0
            for chunk in rsp.iter_content(chunk_size=self.buffer):
                if not chunk:
                    break
                self.fileobj.seek(offset)
                self.fileobj.write(chunk)
                offset = offset + len(chunk)
                proess = offset / int(self.filesize) * 100
                self.download_proess_signal.emit(int(proess))
            self.fileobj.close()
            self.exit(0)

        except Exception as e:
            print(e)